#include <stdio.h>
#include <iostream>
#include <fstream>
#include <log.hpp>
#include <memfs.h>

CLog clg;

int timetrace(Mshell &trace, Mshell &ops);

extern "C" int MAIN(int argc, char **argv)
{
  Mfs tfs, ofs;
  Mshell trace(tfs), ops(ofs);

  if (argc != 3)
  {
    clg.err() << "Usage: " << argv[0] << " <trace> <benchmarked operations>" << std::endl;
    return -1;
  }

  std::ifstream tif(argv[1]);
  XMLParser txp(tif);
  trace.Import(txp, "/");
  
  std::ifstream oif(argv[2]);
  XMLParser oxp(oif);
  ops.Import(oxp, "/");
  
  timetrace(trace, ops);

  std::ofstream tof(argv[1]);
  XMLParser rxp(tof);
  trace.Export(rxp, "/");
  
  return 0;
}

int timetrace(Mshell &trace, Mshell &ops)
{
  char *element;
  int type, line, proc;
  char *name;
  char buf[PATH_MAX];
  unsigned long long int time;

  trace.FindInitDirectoryElements("/trace/operations");
  while (!trace.FindGetNextElement(&element))
  {
    trace.ChDir(element);
    trace.GetContent("type", &type);
    trace.GetContent("line", &line);
    trace.GetContent("processor", &proc);

    sprintf(buf, "/trace/processors/%d/name", proc);
    if (trace.GetContent(buf, &name))
    {
      clg.err() << "Inconsistent trace: processor " << proc
		<< ", referenced by operation " << element << ", doesn't exist" << std::endl;
      return -1;
    }

    sprintf(buf, "/operations/%d/instantiations/%d/%s/time", type, line, name);
    if (ops.GetContent(buf, &time))
    {
      clg.warning() << "Operation type " << type << " on line " << line
		    << " was not benchmarked for processor " << name << std::endl;
      time = 0;
    }

    trace.SetContent("time", time);
  }

  return 0;
}
